package moddbbackendrevisited.resource;

import java.awt.image.BufferedImage;
import java.io.*;
import java.sql.*;
import javax.imageio.ImageIO;
import javax.mail.BodyPart;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMultipart;
import moddbbackendrevisited.schema.*;
import javax.ws.rs.*;
import javax.ws.rs.core.*;
import javax.ws.rs.core.Response.*;
import moddbbackendrevisited.Main;

@Path("/tables/{tableName}/rows/{rowId}/{columnName}")
public class RowResource {

  @Context
  protected UriInfo uriInfo;
  
  /*
   * Read a Row Entry from a Table
   * http://code.google.com/p/moddb08/wiki/BackendInterfaceVersionOne#Read_a_Row_Entry_from_a_Table
   */
  @GET
  public Response get(@PathParam("tableName") String tableName,
                      @PathParam("rowId") int rowId,
                      @PathParam("columnName") String columnName) {

    ResultSet rs;
    String columnMime;
    String fullColumnName;

    try {
      System.out.println("cn: " + columnName);
      // Get chosen columns for chosen table
      rs = Main.dbCon.getMetaData().getColumns(null, null, tableName, columnName + "%");
        
      if (rs.next()) {
        // Column found, get full name (including mime)
        fullColumnName = rs.getString("COLUMN_NAME");
        rs.close();

        // Parse mime from full name
        // FIXME: should check if no ';' exist
        columnMime = fullColumnName.substring(fullColumnName.lastIndexOf(';') + 1);
                
				if (columnMime.equals("image/jpeg")) {
					try {
						Thread.sleep(3000);
					} catch (Exception e) {
						
					}
				}

        Statement stmnt = Main.dbCon.createStatement();
        
        // Select row entry for chosen table, column and row id
        rs = stmnt.executeQuery("SELECT \"" + fullColumnName + "\" FROM " + tableName + " WHERE \"id;text/plain\" = " + rowId);

        if (rs.next()) {
          // Entry read, get it as a byte buffer
          byte[] bs = rs.getBytes(1);
          
          if (bs != null) {
            // Success, return it in the respone as the columns mime type  
            System.out.println("getting " + bs.length + " bytes");              
            rs.close();
            return Response.ok(bs, columnMime).build();
          } else {
            // Empty row entry, respond with NO CONTENT
            System.out.println("no content");
            rs.close();
            return Response.status(Status.NO_CONTENT).build();
          }
        } else {
          // Row entry not found, 404
          rs.close();
          return Response.status(Status.NOT_FOUND).build();
        }

      } else {
        // Column not found, 404
        rs.close();
        return Response.status(Status.NOT_FOUND).build();
      }

    } catch (SQLException e) {
      // SERVICE UNAVAILABLE on error
      e.printStackTrace();
      return Response.status(Status.SERVICE_UNAVAILABLE).build();
    }
  }

  /*@POST
    @Consumes("multipart/*")
    public Response post(@PathParam("tableName") String tableName,
                         @PathParam("rowId") int rowId,
                         @PathParam("columnName") String columnName,
                         MimeMultipart multiPart) throws MessagingException, IOException {

        System.out.println("POSTing");
        //System.out.println(multiPart.getContentType());
        //System.out.println(multiPart.getCount());
        //System.out.println(multiPart.getBodyPart(0).getContentType());

        try {
            String fullColumnName = ColumnsResource.getFullColumnName(tableName, columnName);
            PreparedStatement pstmnt = Main.dbCon.prepareStatement("UPDATE " + tableName + " SET \"" + fullColumnName + "\" = ? WHERE \"id;text/plain\" = ?");

            BodyPart part = multiPart.getBodyPart(0);

            InputStream in = part.getInputStream();
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            
            byte[] buffer = new byte[1024];
            int bytesRead = -1;

            while((bytesRead = in.read(buffer)) > -1) {
                out.write(buffer, 0, bytesRead);
            }

            in.close();
                     
            pstmnt.setBytes(1, out.toByteArray());
            pstmnt.setInt(2, rowId);

            pstmnt.executeUpdate();

        } catch (SQLException e) {
            e.printStackTrace();
            return Response.status(Status.BAD_REQUEST).build();
        }

        return Response.created(uriInfo.getAbsolutePath().resolve("/tables/" + tableName + "/rows/" + rowId + "/" + columnName)).build();
    }
  */

  /*
   * Set/Update a Row Entry in a Table
   * http://code.google.com/p/moddb08/wiki/BackendInterfaceVersionOne#Set/Update_a_Row_Entry_in_a_Table
   */
	@PUT
	public Response put(@PathParam("tableName") String tableName,
	                    @PathParam("rowId") int rowId,
	                    @PathParam("columnName") String columnName,
	                    byte[] bs) {
		
		System.out.println("PUTing");
		
		try {
		  // FIXME: 404 on fullColumnName null
      String fullColumnName = ColumnsResource.getFullColumnName(tableName, columnName);
      
      // Build prepared statament, Insert into chosen table, column and row
      PreparedStatement pstmnt = Main.dbCon.prepareStatement("UPDATE " + tableName + " SET \"" + fullColumnName + "\" = ? WHERE \"id;text/plain\" = ?");
      
      // Select putted data
      pstmnt.setBytes(1, bs);
      // Chosen row
      pstmnt.setInt(2, rowId);
      // Engage..
      pstmnt.executeUpdate();
      
		 } catch (SQLException e) {
		    // Bad request on error
        e.printStackTrace();	
       	return Response.status(Status.BAD_REQUEST).build();
     }
    
    // Created and location
		return Response.created(uriInfo.getAbsolutePath().resolve("/tables/" + tableName + "/rows/" + rowId + "/" + columnName)).build();
	}
}
